// 依赖：npm i jsonwebtoken
const jwt = require('jsonwebtoken');
const fs = require('fs');

// 3. 获取最新的AuthToken（优先确保此方法执行后能够成功获取Token）
function getAuthToken(){
  let privateJson;
  try {
    // readFileSync首个参数修改为private.json的实际路径
    const data = fs.readFileSync('private.json', 'utf8');
    privateJson = JSON.parse(data);
    // 自定义Header
    const header = {
      alg: 'PS256', // 建议使用PS256算法
      kid: privateJson?.key_id,
      typ: 'JWT'    // 类型为JWT
    };
    // 创建JWT载荷
    const payload = {
      iss: privateJson?.sub_account,
      aud: 'https://oauth-login.cloud.huawei.com/oauth2/v3/token', // 实际开发时请将公网地址存储在配置文件或数据库
      iat: Math.floor(Date.now() / 1000),
      exp: Math.floor(Date.now() / 1000) + 3600
    };
    const private_key = privateJson?.private_key;
    // 将字符串中的 \\n 替换成真正的换行符 \n，再按换行符分割为数组
    const lines = private_key.replace(/\\n/g, '\n').split('\n');
    // 取前三行
    const firstThreeLines = lines.slice(0, 3);
    // 重新拼接成一个三行的字符串：
    const PRIVATE_KEY = firstThreeLines.join('\n');
    // 获取鉴权令牌
    const token = jwt.sign(payload, PRIVATE_KEY, { algorithm: 'PS256', header: header });
    
    console.log("生成新令牌：",token);
    // saveTokenToCache(token) //本地文件缓存AuthToken
    return token
  } catch (error) {
    console.error("处理文件时出错:", error);
    return null
  }
}


const path = require('path');

// 缓存文件路径（当前目录下的tokenCache.json）
const CACHE_PATH = path.join(__dirname, 'tokenCache.json');
// 缓存有效期（秒），设置为比JWT有效期短5分钟（300秒）
const CACHE_EXPIRATION_BUFFER = 3000;

// 2. 读取缓存令牌
function getCachedToken() {
  try {
    if (fs.existsSync(CACHE_PATH)) {
      const cacheData = fs.readFileSync(CACHE_PATH, 'utf8');
      const { token, expiresAt } = JSON.parse(cacheData);
      
      // 检查缓存是否有效（当前时间小于过期时间）
      if (Date.now() < expiresAt * 1000) {
        return token;
      }
    }
  } catch (error) {
    console.error('读取缓存失败:', error);
  }
  return null;
}

// 4. 保存令牌到缓存
function saveTokenToCache(token) {
  try {
    // 解析令牌获取过期时间
    const decoded = jwt.decode(token);
    if (!decoded || !decoded.exp) {
      throw new Error('无效的JWT令牌');
    }

    // 计算实际缓存过期时间（提前5分钟失效）
    const cacheExpiresAt = decoded.exp - CACHE_EXPIRATION_BUFFER;
    
    const cacheData = JSON.stringify({
      token,
      expiresAt: cacheExpiresAt
    });

    fs.writeFileSync(CACHE_PATH, cacheData);
    console.log('令牌已缓存');
  } catch (error) {
    console.error('缓存令牌失败:', error);
  }
}

// 1. 带缓存的令牌获取方法
function getTokenWithCache() {
  // 尝试从缓存获取
  const cachedToken = getCachedToken();
  if (cachedToken) {
    console.log('使用缓存令牌');
    return cachedToken;
  }

  // 生成新令牌
  const newToken = getAuthToken();
  if (newToken) {
    saveTokenToCache(newToken);
  }
  return newToken;
}

module.exports = {
  getTokenWithCache
}